#pragma once

#include "InnerMath.hpp"
#include "Reference.hpp"

class Object;
class Renderer : public Reference
{
public:
    Renderer();
    ~Renderer();

    int addObject(Object* obj);

    void setLight(const vec3& pos, const vec4& color);

    void clearAll();

    inline void setLookAt(const vec3& eye, const vec3& center, const vec3& up) { _view = glm::lookAt(eye, center, up); }

    inline void setPerspective(scalar fov, scalar width, scalar height, scalar znear, scalar zfar) { _proj = glm::perspectiveFov(fov, width, height, znear, zfar); }

    inline void setViewMatrix(const mat4& m) { _view = m; }

    inline void setProjectionMatrix(const mat4& m) { _proj = m; }

    inline void setViewport(int x, int y, int w, int h)
    {
        mat4 m; 
        m = glm::translate(m, vec3(x, y, 0));
        m = glm::scale(m, vec3(w*0.5, h*0.5, 0.5));
        m = glm::translate(m, vec3(1, 1, 1));
        _window = m;
    }

    void render(uint w, uint h, uint bpp, void* raw_data);

protected:

    //void tracer();

    mat4 _view;
    mat4 _proj;
    mat4 _window;

    vec3 _lightPos = vec3(0);
    vec4 _lightColor = vec4(1);

    std::vector<ref_ptr<Object>> _objs;
    
};

